package class12;

import class10.TreeTools.*;

/**
 * <a href="https://leetcode.cn/problems/balanced-binary-tree/">110. 平衡二叉树</a>
 */
public class Code03_IsBalanced {

    // 记录二叉树的信息
    public static class Info {
        int height;
        boolean isBalance;

        Info(int height, boolean isBalance) {
            this.height = height;
            this.isBalance = isBalance;
        }
    }

    public static Info isBalanced(TreeNode root) {
        // base case
        if (root == null) {
            return new Info(0, true);
        }
        // 向左边要信息
        Info left = isBalanced(root.left);
        // 向右边要信息
        Info right = isBalanced(root.right);
        // 获取信息情况，就是将left和right收集到的信息进行一个汇总
        // 当前二叉树结点的高度
        int height = Math.max(left.height, right.height) + 1;
        // 当前二叉树是否是平衡二叉树，需要进行判断
        boolean isBalance = left.isBalance && right.isBalance && Math.abs(left.height - right.height) <= 1;
        // 返回当前结点的信息情况
        return new Info(height, isBalance);
    }


    public static boolean isBalanced1(TreeNode head) {
        boolean[] ans = new boolean[1];
        ans[0] = true;
        process1(head, ans);
        return ans[0];
    }

    public static int process1(TreeNode head, boolean[] ans) {
        if (!ans[0] || head == null) {
            return -1;
        }
        int leftHeight = process1(head.left, ans);
        int rightHeight = process1(head.right, ans);
        if (Math.abs(leftHeight - rightHeight) > 1) {
            ans[0] = false;
        }
        return Math.max(leftHeight, rightHeight) + 1;
    }

    // for test
    public static TreeNode generateRandomBST(int maxLevel, int maxValue) {
        return generate(1, maxLevel, maxValue);
    }

    // for test
    public static TreeNode generate(int level, int maxLevel, int maxValue) {
        if (level > maxLevel || Math.random() < 0.5) {
            return null;
        }
        TreeNode head = new TreeNode((int) (Math.random() * maxValue));
        head.left = generate(level + 1, maxLevel, maxValue);
        head.right = generate(level + 1, maxLevel, maxValue);
        return head;
    }

    public static void main(String[] args) {
        int maxLevel = 5;
        int maxValue = 100;
        int testTimes = 1000000;
        for (int i = 0; i < testTimes; i++) {
            TreeNode head = generateRandomBST(maxLevel, maxValue);
            if (isBalanced(head).isBalance != isBalanced1(head)) {
                System.out.println("Oops!");
            }
        }
        System.out.println("finish!");
    }
}
